package cn.wolfcode.luowowo.member.service.impl;

import cn.wolfcode.luowowo.cache.service.IUserInfoRedisService;
import cn.wolfcode.luowowo.common.exception.LogicException;
import cn.wolfcode.luowowo.common.util.AssertUtil;
import cn.wolfcode.luowowo.common.util.Consts;
import cn.wolfcode.luowowo.member.domain.UserInfo;
import cn.wolfcode.luowowo.member.mapper.UserInfoMapper;
import cn.wolfcode.luowowo.member.service.IUserInfoService;
import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.UUID;

//@Transactional 涉及到分布式事务操作， 项目四再说
@Service
public class UserInfoServiceImpl implements IUserInfoService {

    //@Reference  //2 垮服务调用时候，使用， 他拥有RPC功能
    @Autowired  //1 在同一个服务里面使用
    private UserInfoMapper userInfoMapper;


    @Reference
    private IUserInfoRedisService userInfoRedisServie;


    @Override
    public UserInfo get(Long id) {
        return userInfoMapper.selectByPrimaryKey(id);
    }

    @Override
    public boolean checkPhone(String phone) {
        int count = userInfoMapper.selectCountByPhone(phone);
        return count > 0;
    }

    @Override
    public void sendVerifyCode(String phone) {
        //创建验证码
        String code =  UUID.randomUUID().toString()
                .replaceAll("-", "").substring(0, 4);
        //模拟短信发送
        StringBuilder sb = new StringBuilder(100);
        sb.append("注册短信的验证码为：").append(code).append(", 请在").append(Consts.VERIFY_CODE_VAI_TIME).append("分钟之内使用");
        System.out.println(sb.toString());

        //code 保存到redis上
        userInfoRedisServie.addVerifyCode(phone, code);
    }

    @Override
    public void userRegist(String phone, String nickname, String password, String rpassword, String verifyCode)  throws LogicException{
        //1：参数是否为空检验
        AssertUtil.hasLength(phone, "手机号码不能为空");
        AssertUtil.hasLength(nickname, "昵称不能为空");
        AssertUtil.hasLength(password, "密码不能为空");
        AssertUtil.hasLength(rpassword, "确认不能为空");
        AssertUtil.hasLength(verifyCode, "短信验证码不能为空");

        //2：2次密码输入是否正确
        AssertUtil.isEquals(password,rpassword, "两次输入密码必须一致");

        //3：手机号码格式是否正确 TODO [拓展：java的正则表达式]


        //4：手机号码是否不是唯一
        if(this.checkPhone(phone)){
            throw new LogicException("该手机号码已经被注册了");
        }

        //5：短信验证码是否一致
        String code = userInfoRedisServie.getVerfiyCode(phone);

        if(code == null || !code.equalsIgnoreCase(verifyCode)){
            throw new LogicException("短信验证码错误或者失效");
        }
        //6：用户注册
        UserInfo user =  new UserInfo();

        user.setNickname(nickname);
        user.setPhone(phone);
        user.setPassword(password);   //假装已经加密
        user.setHeadImgUrl("/images/default.jpg");
        user.setLevel(1);
        user.setState(UserInfo.STATE_NORMAL);

        userInfoMapper.insert(user);
    }

    @Override
    public String userLogin(String username, String password) throws LogicException {

        //1：获取参数： username跟password
        //2：作为sql参数数查询userInfo对象
        UserInfo  userInfo = userInfoMapper.selectUserByUsernameAndPassword(username,password );


        //3：判断userInfo对象是否存在
        //4：如果不存在，提示账号或密码错误
        if(userInfo == null){
            throw  new LogicException("账号或密码错误");
        }
        //5：如果存在，表示登录成功
        //6：使用UUID创建随机的令牌(token)
        String token = UUID.randomUUID().toString().replaceAll("-", "");
        //7：将token的值作为redis的key，userInfo则为value值
        userInfoRedisServie.setToken(token, userInfo);

        //缓存到redis数据库中, 注意：设置token有效时间是：30分数



        return token;
    }

    @Override
    public List<UserInfo> list() {
        return userInfoMapper.selectAll();
    }
}
